home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / lisp / kcl / kcl.lha / c / pathname.d < prev    next >
Text File  |  1987-06-04  |  15KB  |  784 lines

  1. /*
  2. (c) Copyright Taiichi Yuasa and Masami Hagiya, 1984.  All rights reserved.
  3. Copying of this file is authorized to users who have executed the true and
  4. proper "License Agreement for Kyoto Common LISP" with SIGLISP.
  5. */
  6.  
  7. /*
  8.     pathname.d
  9.     IMPLEMENTATION-DEPENTENT
  10.  
  11.     This file contains those functions that interpret namestrings.
  12. */
  13.  
  14. #include "include.h"
  15.  
  16. object Vdefault_pathname_defaults;
  17.  
  18. object Kwild;
  19. object Knewest;
  20.  
  21. object Kstart;
  22. object Kend;
  23. object Kjunk_allowed;
  24.  
  25. object Khost;
  26. object Kdevice;
  27. object Kdirectory;
  28. object Kname;
  29. object Ktype;
  30. object Kversion;
  31. object Kdefaults;
  32.  
  33. object Kroot;
  34. object Kcurrent;
  35. object Kparent;
  36. object Kper;
  37.  
  38. object
  39. make_pathname(host, device, directory, name, type, version)
  40. object host, device, directory, name, type, version;
  41. {
  42.     object x;
  43.  
  44.     x = alloc_object(t_pathname);
  45.     x->pn.pn_host = host;
  46.     x->pn.pn_device = device;
  47.     x->pn.pn_directory = directory;
  48.     x->pn.pn_name = name;
  49.     x->pn.pn_type = type;
  50.     x->pn.pn_version = version;
  51.     return(x);
  52. }
  53.  
  54. static
  55. make_one(s, end)
  56. char *s;
  57. int end;
  58. {
  59.     int i;
  60.  
  61. #ifdef UNIX
  62.     for (i = 0;  i < end;  i++)
  63.         token->st.st_self[i] = s[i];
  64. #endif
  65. #ifdef AOSVS
  66.  
  67.  
  68.  
  69. #endif
  70.     token->st.st_fillp = end;
  71.     vs_push(copy_simple_string(token));
  72. }
  73.  
  74. /* !!!!! Bug Fix. NLG */
  75. object
  76. parse_namestring(s, start, end, ep)
  77. object s;
  78. int start, end, *ep;
  79. {
  80.     int i, j, k;
  81.     int d;
  82.     object *vsp;
  83.     object x;
  84.     vs_mark;
  85.  
  86.     vsp = vs_top + 1;
  87.     for (i = j = start;  i < end;  ) {
  88.         if (isspace(s->st.st_self[i]))
  89.             break;
  90. #ifdef UNIX
  91.         if (s->st.st_self[i] == '/') {
  92. #endif
  93. #ifdef AOSVS
  94.  
  95. #endif
  96.             if (j == 0 && i == 0) {
  97.                 i++;
  98.                 vs_push(Kroot);
  99.                 j = i;
  100.                 continue;
  101.             }
  102. #ifdef UNIX
  103.             /* BUG FIX by Grant J. Munsey */
  104.             if (i == j) {
  105.                 i++;
  106.                 j = i;
  107.                 continue;
  108.             }
  109.             /* END OF BUG FIX */
  110. #endif
  111. #ifdef AOSVS
  112.  
  113.  
  114. #endif
  115. #ifdef UNIX
  116.             if (i-j == 1 && s->st.st_self[j] == '.') {
  117.                 vs_push(Kcurrent);
  118.             } else if (i-j==2 && s->st.st_self[j]=='.' && s->st.st_self[j+1]=='.') {
  119.                 vs_push(Kparent);
  120.             } else
  121.                 make_one(&s->st.st_self[j], i-j);
  122. #endif
  123. #ifdef AOSVS
  124.  
  125. #endif
  126.             i++;
  127.             j = i;
  128. #ifdef AOSVS
  129.  
  130.  
  131.  
  132.  
  133.  
  134.  
  135.  
  136.  
  137.  
  138.  
  139.  
  140.  
  141.  
  142.  
  143.  
  144.  
  145.  
  146.  
  147.  
  148.  
  149.  
  150.  
  151.  
  152.  
  153.  
  154.  
  155. #endif
  156.         } else
  157.             i++;
  158.     }
  159. #ifdef UNIX
  160. /*
  161.     if (i-j == 1 && s->st.st_self[j] == '.') {
  162.         vs_push(Kcurrent);
  163.         j = i;
  164.     } else if (i-j == 2 && s->st.st_self[j] == '.' && s->st.st_self[j+1] == '.') {
  165.         vs_push(Kparent);
  166.         j = i;
  167.     }
  168. */
  169. #endif
  170.     *ep = i;
  171.     vs_push(Cnil);
  172.     while (vs_top > vsp)
  173.         stack_cons();
  174.     if (i == j) {
  175.         /*  no file and no type  */
  176.         vs_push(Cnil);
  177.         vs_push(Cnil);
  178.         goto L;
  179.     }
  180.     for (k = j, d = -1;  k < i;  k++)
  181.         if (s->st.st_self[k] == '.')
  182.             d = k;
  183.     if (d == -1) {
  184.         /*  no file type  */
  185. #ifdef UNIX
  186.         if (i-j == 1 && s->st.st_self[j] == '*')
  187. #endif
  188. #ifdef AOSVS
  189.  
  190. #endif
  191.             vs_push(Kwild);
  192.         else
  193.             make_one(&s->st.st_self[j], i-j);
  194.         vs_push(Cnil);
  195.     } else if (d == j) {
  196.         /*  no file name  */
  197.         vs_push(Cnil);
  198. #ifdef UNIX
  199.         if (i-d-1 == 1 && s->st.st_self[d+1] == '*')
  200. #endif
  201. #ifdef AOSVS
  202.  
  203. #endif
  204.             vs_push(Kwild);
  205.         else
  206.             make_one(&s->st.st_self[d+1], i-d-1);
  207.     } else {
  208.         /*  file name and file type  */
  209. #ifdef UNIX
  210.         if (d-j == 1 && s->st.st_self[j] == '*')
  211. #endif
  212. #ifdef AOSVS
  213.  
  214. #endif
  215.             vs_push(Kwild);
  216.         else
  217.             make_one(&s->st.st_self[j], d-j);
  218. #ifdef UNIX
  219.         if (i-d-1 == 1 && s->st.st_self[d+1] == '*')
  220. #endif
  221. #ifdef AOSVS
  222.  
  223. #endif
  224.             vs_push(Kwild);
  225.         else
  226.             make_one(&s->st.st_self[d+1], i-d-1);
  227.     }
  228. L:
  229.     x
  230.     = make_pathname(Cnil, Cnil,
  231.             vs_top[-3], vs_top[-2], vs_top[-1], Cnil);
  232.     vs_reset;
  233.     return(x);
  234.  
  235. NO:
  236.     *ep = i;
  237.     vs_reset;
  238.     return(OBJNULL);
  239. }
  240.  
  241. object
  242. coerce_to_pathname(x)
  243. object x;
  244. {
  245.     object y;
  246.     int e;
  247.  
  248. L:
  249.     switch (type_of(x)) {
  250.     case t_symbol:
  251.     case t_string:
  252.                 /* !!!!! Bug Fix. NLG */
  253.         y = parse_namestring(x, 0, x->st.st_fillp, &e);
  254.         if (y == OBJNULL || e != x->st.st_fillp)
  255.             goto CANNOT_COERCE;
  256.         return(y);
  257.  
  258.     case t_pathname:
  259.         return(x);
  260.  
  261.     case t_stream:
  262.         switch (x->sm.sm_mode) {
  263.         case smm_input:
  264.         case smm_output:
  265.         case smm_probe:
  266.         case smm_io:
  267.             x = x->sm.sm_object1;
  268.             /*
  269.                 The file was stored in sm.sm_object1.
  270.                 See open.
  271.             */
  272.             goto L;
  273.  
  274.         case smm_synonym:
  275.             x = symbol_value(x->sm.sm_object0);
  276.             goto L;
  277.  
  278.         default:
  279.             goto CANNOT_COERCE;
  280.         }
  281.  
  282.     default:
  283.     CANNOT_COERCE:
  284.         FEerror("~S cannot be coerced to a pathname.", 1, x);
  285.     }
  286. }
  287.  
  288. object
  289. default_device(host)
  290. object host;
  291. {
  292.     return(Cnil);
  293.     /*  not implemented yet  */
  294. }
  295.  
  296. object
  297. merge_pathnames(path, defaults, default_version)
  298. object path, defaults, default_version;
  299. {
  300.     object host, device, directory, name, type, version;
  301.  
  302.     if (path->pn.pn_host == Cnil)
  303.         host = defaults->pn.pn_host;
  304.     else
  305.         host = path->pn.pn_host;
  306.     if (path->pn.pn_device == Cnil)
  307.         if (path->pn.pn_host == Cnil)
  308.             device = defaults->pn.pn_device;
  309.         else if (path->pn.pn_host == defaults->pn.pn_host)
  310.             device = defaults->pn.pn_device;
  311.         else
  312.             device = default_device(path->pn.pn_host);
  313.     else
  314.         device = path->pn.pn_device;
  315.     if (path->pn.pn_directory == Cnil)
  316.         directory = defaults->pn.pn_directory;
  317.     else
  318.         directory = path->pn.pn_directory;
  319.     if (path->pn.pn_name == Cnil)
  320.         name = defaults->pn.pn_name;
  321.     else
  322.         name = path->pn.pn_name;
  323.     if (path->pn.pn_type == Cnil)
  324.         type = defaults->pn.pn_type;
  325.     else
  326.         type = path->pn.pn_type;
  327.     version = Cnil;
  328.     /*
  329.         In this implimentation, version is not counted
  330.     */
  331.     return(make_pathname(host,device,directory,name,type,version));
  332. }
  333.  
  334. /*
  335.     Namestring(x) converts a pathname to a namestring.
  336. */
  337. object
  338. namestring(x)
  339. object x;
  340. {
  341.     int i, j;
  342.     object l, y;
  343.  
  344.     i = 0;
  345.     l = x->pn.pn_directory;
  346.     if (endp(l))
  347.         goto L;
  348.     y = l->c.c_car;
  349.     if (y == Kroot) {
  350. #ifdef UNIX
  351.         token->st.st_self[i++] = '/';
  352. #endif
  353. #ifdef AOSVS
  354.  
  355. #endif
  356.         l = l->c.c_cdr;
  357.     }
  358. #ifdef AOSVS
  359.  
  360.  
  361.  
  362.  
  363.  
  364.  
  365.  
  366.  
  367.  
  368.  
  369.  
  370.  
  371.  
  372. #endif
  373.     for (;  !endp(l);  l = l->c.c_cdr) {
  374.         y = l->c.c_car;
  375. #ifdef UNIX
  376.         if (y == Kcurrent) {
  377.             token->st.st_self[i++] = '.';
  378.             token->st.st_self[i++] = '/';
  379.             continue;
  380.         } else if (y == Kparent) {
  381.             token->st.st_self[i++] = '.';
  382.             token->st.st_self[i++] = '.';
  383.             token->st.st_self[i++] = '/';
  384.             continue;
  385.         }
  386. #endif
  387.         y = coerce_to_string(y);
  388.         for (j = 0;  j < y->st.st_fillp;  j++)
  389.             token->st.st_self[i++]
  390.             = y->st.st_self[j];
  391. #ifdef UNIX
  392.         token->st.st_self[i++] = '/';
  393. #endif
  394. #ifdef AOSVS
  395.  
  396. #endif
  397.     }
  398. L:
  399.     y = x->pn.pn_name;
  400.     if (y == Cnil)
  401.         goto M;
  402.     if (y == Kwild) {
  403. #ifdef UNIX
  404.         token->st.st_self[i++] = '*';
  405. #endif
  406. #ifdef AOSVS
  407.  
  408. #endif
  409.         goto M;
  410.     }
  411.     if (type_of(y) != t_string)
  412.         FEerror("~S is an illegal pathname name.", 1, y);
  413.     for (j = 0;  j < y->st.st_fillp;  j++)
  414.         token->st.st_self[i++] = y->st.st_self[j];
  415. M:
  416.     y = x->pn.pn_type;
  417.     if (y == Cnil)
  418.         goto N;
  419.     if (y == Kwild) {
  420.         token->st.st_self[i++] = '.';
  421. #ifdef UNIX
  422.         token->st.st_self[i++] = '*';
  423. #endif
  424. #ifdef AOSVS
  425.  
  426. #endif
  427.         goto N;
  428.     }
  429.     if (type_of(y) != t_string)
  430.         FEerror("~S is an illegal pathname name.", 1, y);
  431.     token->st.st_self[i++] = '.';
  432.     for (j = 0;  j < y->st.st_fillp;  j++)
  433.         token->st.st_self[i++] = y->st.st_self[j];
  434. N:
  435.     token->st.st_fillp = i;
  436.     return(copy_simple_string(token));
  437. }
  438.  
  439. object
  440. coerce_to_namestring(x)
  441. object x;
  442. {
  443.     object y;
  444.     int e;
  445.  
  446. L:
  447.     switch (type_of(x)) {
  448.     case t_symbol:
  449.         vs_push(alloc_simple_string(x->s.s_fillp));
  450.         /* By Nick Gall */
  451.         vs_head->st.st_self = alloc_relblock(x->s.s_fillp);
  452.         {
  453.             int i;
  454.             for (i = 0;  i < x->s.s_fillp;  i++)
  455.                 vs_head->st.st_self[i] = x->s.s_self[i];
  456.         }
  457.         return(vs_pop);
  458.  
  459.     case t_string:
  460.         return(x);
  461.  
  462.     case t_pathname:
  463.         return(namestring(x));
  464.  
  465.     case t_stream:
  466.         switch (x->sm.sm_mode) {
  467.         case smm_input:
  468.         case smm_output:
  469.         case smm_probe:
  470.         case smm_io:
  471.             x = x->sm.sm_object1;
  472.             /*
  473.                 The file was stored in sm.sm_object1.
  474.                 See open.
  475.             */
  476.             goto L;
  477.  
  478.         case smm_synonym:
  479.             x = symbol_value(x->sm.sm_object0);
  480.             goto L;
  481.  
  482.         default:
  483.             goto CANNOT_COERCE;
  484.         }
  485.  
  486.     default:
  487.     CANNOT_COERCE:
  488.         FEerror("~S cannot be coerced to a namestring.", 1, x);
  489.     }
  490. }
  491.  
  492. Lpathname()
  493. {
  494.     check_arg(1);
  495.     check_type_or_pathname_string_symbol_stream(&vs_base[0]);
  496.     vs_base[0] = coerce_to_pathname(vs_base[0]);
  497. }
  498.  
  499. @(defun parse_namestring (thing
  500.     &o host
  501.        (defaults `symbol_value(Vdefault_pathname_defaults)`)
  502.     &k start end junk_allowed
  503.     &a x y)
  504.     int s, e, ee;
  505. @
  506.     check_type_or_pathname_string_symbol_stream(&thing);
  507.     check_type_or_pathname_string_symbol_stream(&defaults);
  508.     defaults = coerce_to_pathname(defaults);
  509.     x = thing;
  510. L:
  511.     switch (type_of(x)) {
  512.     case t_symbol:
  513.     case t_string:
  514.         get_string_start_end(x, start, end, &s, &e);
  515.         for (;  s < e && isspace(x->st.st_self[s]);  s++)
  516.             ;
  517.         y
  518.                   /* !!!!! Bug Fix. NLG */
  519.         = parse_namestring(x,
  520.                                    s,
  521.                    e - s,
  522.                    &ee);
  523.         if (junk_allowed == Cnil) {
  524.             for (;  ee < e - s;  ee++)
  525.                 if (!isspace(x->st.st_self[s + ee]))
  526.                     break;
  527.             if (y == OBJNULL || ee != e - s)
  528.                 FEerror("Cannot parse the namestring ~S~%\
  529. from ~S to ~S.",
  530.                     3, x, start, end);
  531.         } else
  532.             if (y == OBJNULL)
  533.                 @(return Cnil `make_fixnum(s + ee)`)
  534.         start = make_fixnum(s + ee);
  535.         break;
  536.  
  537.     case t_pathname:
  538.         y = x;
  539.         break;
  540.  
  541.     case t_stream:
  542.         switch (x->sm.sm_mode) {
  543.         case smm_input:
  544.         case smm_output:
  545.         case smm_probe:
  546.         case smm_io:
  547.             x = x->sm.sm_object1;
  548.             /*
  549.                 The file was stored in sm.sm_object1.
  550.                 See open.
  551.             */
  552.             goto L;
  553.  
  554.         case smm_synonym:
  555.             x = symbol_value(x->sm.sm_object0);
  556.             goto L;
  557.  
  558.         default:
  559.             goto CANNOT_PARSE;
  560.         }
  561.  
  562.     default:
  563.     CANNOT_PARSE:
  564.         FEerror("Cannot parse the namestring ~S.", 1, x);
  565.     }
  566.     if (host != Cnil && y->pn.pn_host != Cnil &&
  567.         host != y->pn.pn_host)
  568.         FEerror("The hosts ~S and ~S do not match.",
  569.             2, host, y->pn.pn_host);
  570.     @(return y start)
  571. @)
  572.  
  573. @(defun merge_pathnames (path
  574.     &o (defaults `symbol_value(Vdefault_pathname_defaults)`)
  575.         (default_version Knewest))
  576. @
  577.     check_type_or_pathname_string_symbol_stream(&path);
  578.     check_type_or_pathname_string_symbol_stream(&defaults);
  579.     path = coerce_to_pathname(path);
  580.     defaults = coerce_to_pathname(defaults);
  581.     @(return `merge_pathnames(path, defaults, default_version)`)
  582. @)
  583.  
  584. @(defun make_pathname (&key host device directory name
  585.                 type version defaults
  586.                &aux x)
  587. @
  588.     if (defaults == Cnil) {
  589.         defaults
  590.         = symbol_value(Vdefault_pathname_defaults);
  591.         defaults = coerce_to_pathname(defaults);
  592.         defaults
  593.         = make_pathname(defaults->pn.pn_host,
  594.                     Cnil, Cnil, Cnil, Cnil, Cnil);
  595.     } else
  596.         defaults = coerce_to_pathname(defaults);
  597.     x = make_pathname(host, device, directory, name, type, version);
  598.     x = merge_pathnames(x, defaults, Cnil);
  599.     @(return x)
  600. @)
  601.  
  602. Lpathnamep()
  603. {
  604.     check_arg(1);
  605.  
  606.     if (type_of(vs_base[0]) == t_pathname)
  607.         vs_base[0] = Ct;
  608.     else
  609.         vs_base[0] = Cnil;
  610. }
  611.  
  612. Lpathname_host()
  613. {
  614.     check_arg(1);
  615.  
  616.     check_type_or_pathname_string_symbol_stream(&vs_base[0]);
  617.     vs_base[0] = coerce_to_pathname(vs_base[0]);
  618.     vs_base[0] = vs_base[0]->pn.pn_host;
  619. }
  620.  
  621. Lpathname_device()
  622. {
  623.     check_arg(1);
  624.  
  625.     check_type_or_pathname_string_symbol_stream(&vs_base[0]);
  626.     vs_base[0] = coerce_to_pathname(vs_base[0]);
  627.     vs_base[0] = vs_base[0]->pn.pn_device;
  628. }
  629.  
  630. Lpathname_directory()
  631. {
  632.     check_arg(1);
  633.  
  634.     check_type_or_pathname_string_symbol_stream(&vs_base[0]);
  635.     vs_base[0] = coerce_to_pathname(vs_base[0]);
  636.     vs_base[0] = vs_base[0]->pn.pn_directory;
  637. }
  638.  
  639. Lpathname_name()
  640. {
  641.     check_arg(1);
  642.  
  643.     check_type_or_pathname_string_symbol_stream(&vs_base[0]);
  644.     vs_base[0] = coerce_to_pathname(vs_base[0]);
  645.     vs_base[0] = vs_base[0]->pn.pn_name;
  646. }
  647.  
  648. Lpathname_type()
  649. {
  650.     check_arg(1);
  651.  
  652.     check_type_or_pathname_string_symbol_stream(&vs_base[0]);
  653.     vs_base[0] = coerce_to_pathname(vs_base[0]);
  654.     vs_base[0] = vs_base[0]->pn.pn_type;
  655. }
  656.  
  657. Lpathname_version()
  658. {
  659.     check_arg(1);
  660.  
  661.     check_type_or_pathname_string_symbol_stream(&vs_base[0]);
  662.     vs_base[0] = coerce_to_pathname(vs_base[0]);
  663.     vs_base[0] = vs_base[0]->pn.pn_version;
  664. }
  665.  
  666. Lnamestring()
  667. {
  668.     check_arg(1);
  669.  
  670.     check_type_or_pathname_string_symbol_stream(&vs_base[0]);
  671.     vs_base[0] = coerce_to_namestring(vs_base[0]);
  672. }
  673.  
  674. Lfile_namestring()
  675. {
  676.     check_arg(1);
  677.  
  678.     check_type_or_pathname_string_symbol_stream(&vs_base[0]);
  679.     vs_base[0] = coerce_to_pathname(vs_base[0]);
  680.     vs_base[0]
  681.     = make_pathname(Cnil, Cnil, Cnil,
  682.                 vs_base[0]->pn.pn_name,
  683.                 vs_base[0]->pn.pn_type,
  684.                 vs_base[0]->pn.pn_version);
  685.     vs_base[0] = namestring(vs_base[0]);
  686. }
  687.  
  688. Ldirectory_namestring()
  689. {
  690.     check_arg(1);
  691.  
  692.     check_type_or_pathname_string_symbol_stream(&vs_base[0]);
  693.     vs_base[0] = coerce_to_pathname(vs_base[0]);
  694.     vs_base[0]
  695.     = make_pathname(Cnil, Cnil,
  696.                 vs_base[0]->pn.pn_directory,
  697.                 Cnil, Cnil, Cnil);
  698.     vs_base[0] = namestring(vs_base[0]);
  699. }
  700.  
  701. Lhost_namestring()
  702. {
  703.     check_arg(1);
  704.  
  705.     check_type_or_pathname_string_symbol_stream(&vs_base[0]);
  706.     vs_base[0] = coerce_to_pathname(vs_base[0]);
  707.     vs_base[0] = vs_base[0]->pn.pn_host;
  708.     if (vs_base[0] == Cnil || vs_base[0] == Kwild)
  709.         vs_base[0] = make_simple_string("");
  710. }
  711.  
  712. @(defun enough_namestring (path
  713.     &o (defaults `symbol_value(Vdefault_pathname_defaults)`))
  714. @
  715.     check_type_or_pathname_string_symbol_stream(&path);
  716.     check_type_or_pathname_string_symbol_stream(&defaults);
  717.     defaults = coerce_to_pathname(defaults);
  718.     path = coerce_to_pathname(path);
  719.     path
  720.     = make_pathname(equalp(path->pn.pn_host, defaults->pn.pn_host) ?
  721.             Cnil : path->pn.pn_host,
  722.                     equalp(path->pn.pn_device,
  723.                    defaults->pn.pn_device) ?
  724.             Cnil : path->pn.pn_device,
  725.                     equalp(path->pn.pn_directory,
  726.                    defaults->pn.pn_directory) ?
  727.             Cnil : path->pn.pn_directory,
  728.                     equalp(path->pn.pn_name, defaults->pn.pn_name) ?
  729.             Cnil : path->pn.pn_name,
  730.                     equalp(path->pn.pn_type, defaults->pn.pn_type) ?
  731.             Cnil : path->pn.pn_type,
  732.                     equalp(path->pn.pn_version,
  733.                    defaults->pn.pn_version) ?
  734.             Cnil : path->pn.pn_version);
  735.     @(return `namestring(path)`)
  736. @)
  737.  
  738. init_pathname()
  739. {
  740.     Vdefault_pathname_defaults =
  741.     make_special("*DEFAULT-PATHNAME-DEFAULTS*",
  742.              make_pathname(Cnil, Cnil, Cnil, Cnil, Cnil, Cnil));
  743.  
  744.     Kwild = make_keyword("WILD");
  745.     Knewest = make_keyword("NEWEST");
  746.  
  747.     Kstart = make_keyword("START");
  748.     Kend = make_keyword("END");
  749.     Kjunk_allowed = make_keyword("JUNK-ALLOWED");
  750.  
  751.     Khost = make_keyword("HOST");
  752.     Kdevice = make_keyword("DEVICE");
  753.     Kdirectory = make_keyword("DIRECTORY");
  754.     Kname = make_keyword("NAME");
  755.     Ktype = make_keyword("TYPE");
  756.     Kversion = make_keyword("VERSION");
  757.     Kdefaults = make_keyword("DEFAULTS");
  758.  
  759.     Kroot = make_keyword("ROOT");
  760.     Kcurrent = make_keyword("CURRENT");
  761.     Kparent = make_keyword("PARENT");
  762.     Kper = make_keyword("PER");
  763. }
  764.  
  765. init_pathname_function()
  766. {
  767.     make_function("PATHNAME", Lpathname);
  768.     make_function("PARSE-NAMESTRING", Lparse_namestring);
  769.     make_function("MERGE-PATHNAMES", Lmerge_pathnames);
  770.     make_function("MAKE-PATHNAME", Lmake_pathname);
  771.     make_function("PATHNAMEP", Lpathnamep);
  772.     make_function("PATHNAME-HOST", Lpathname_host);
  773.     make_function("PATHNAME-DEVICE", Lpathname_device);
  774.     make_function("PATHNAME-DIRECTORY", Lpathname_directory);
  775.     make_function("PATHNAME-NAME", Lpathname_name);
  776.     make_function("PATHNAME-TYPE", Lpathname_type);
  777.     make_function("PATHNAME-VERSION", Lpathname_version);
  778.     make_function("NAMESTRING", Lnamestring);
  779.     make_function("FILE-NAMESTRING", Lfile_namestring);
  780.     make_function("DIRECTORY-NAMESTRING", Ldirectory_namestring);
  781.     make_function("HOST-NAMESTRING", Lhost_namestring);
  782.     make_function("ENOUGH-NAMESTRING", Lenough_namestring);
  783. }
  784.